home *** CD-ROM | disk | FTP | other *** search
- /* expr has the grammar: expr ::= expr operator expr | "(" expr ")" ;
- with operator priority taken care of. Resulting value goes to stdout.
- Note that ":" operations are not implemented. This is basically the
- v7expr.c at uunet */
-
- #define MAXPRIO 6
- #define OPERAND 20
- enum opnum {EOI,OR,AND,LT,LE,EQ,NE,GE,GT,ADD,SUB,MUL,DIV,MOD,LPAREN,RPAREN};
-
- struct E_sop { char *text; enum opnum num; short prio;
- }E_ops[]={{"|", OR, 6}, {"&", AND, 5}, {"<", LT, 4}, {"<=", LE, 4},
- {"=", EQ, 4}, {"!=", NE, 4}, {">=", GE, 4}, {">", GT, 4},
- {"+", ADD, 3}, {"-", SUB, 3}, {"*", MUL, 2}, {"/", DIV, 2},
- {"%", MOD, 2}, {"(", LPAREN,0}, {")", RPAREN,0}, {0, 0, 0}};
-
- char **E_ip;
- struct E_sop *E_op;
- int E_error=0;
-
- /* set global E_op to the op and return the opnum or the operand */
- E_lex(char* s) {
- struct E_sop *op=E_ops;
- if (s==0) {
- E_op=0;
- return EOI;
- }
- while (op->text) {
- if (strcmp(s,op->text)==0) {
- E_op=op;
- return op->num;
- }
- op++;
- }
- E_op=0;
- return OPERAND;
- }
-
- int E_expr(int n, short prio) {
- int res;
- if (n==EOI) { E_error=1; return 1; }
- if (n==LPAREN) {
- res=E_expr(E_lex(*++E_ip), MAXPRIO);
- if (E_lex(*++E_ip) != RPAREN) { E_error=1; return 1; }
- return res;
- }
- if (n != OPERAND) { E_error=1; return 1; }
- if (prio == 0) return atoi(*E_ip);
- res = E_expr(n, prio - 1);
- while ((n = E_lex(*++E_ip)) && E_op && E_op->prio == prio)
- res = E_eval(res, n, E_expr(E_lex(*++E_ip), prio - 1));
- E_ip--;
- return res;
- }
-
- int E_eval(int l1, int op, int l2) {
- switch (op) {
- case OR: return l1 ? l1 : l2;
- case AND: return (l1 && l2) ? l1 : 0;
- case LT: return l1 < l2;
- case LE: return l1 <= l2;
- case EQ: return l1 == l2;
- case NE: return l1 != l2;
- case GE: return l1 >= l2;
- case GT: return l1 > l2;
- case ADD: return l1 + l2;
- case SUB: return l1 - l2;
- case MUL: return l1 * l2;
- case DIV: return l1 / l2;
- case MOD: return l1 % l2;
- }
- E_error=1;
- return 1;
- }
-
- #ifdef ADDON
-
- #include "addon.h"
- typedef enum bool { FALSE, TRUE } bool;
- extern void set(bool);
- #define good_bye { set(TRUE); return; }
- #define bad_bye { set(FALSE); return; }
-
- void b_expr(char** argv) {
-
- #else
-
- #define good_bye return 0;
- #define bad_bye return E_error;
-
- int main(int argc, char** argv) {
-
- #endif /* ADDON */
-
- int res;
-
- E_ip=&argv[1];
- res=E_expr(E_lex(*E_ip), MAXPRIO);
-
- if (*++E_ip != 0)
- bad_bye
- printf("%ld\n", res);
- if (E_error==1)
- bad_bye
- else
- good_bye
- }
-